package com.lamatek.tags.google.beans;

import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.lamatek.tags.google.GoogleMapBlowupTag;
import com.lamatek.tags.google.GoogleMapBoxTag;
import com.lamatek.tags.google.GoogleMapCircleTag;
import com.lamatek.tags.google.GoogleMapClusterTag;
import com.lamatek.tags.google.GoogleMapCoordinatesTag;
import com.lamatek.tags.google.GoogleMapEventTag;
import com.lamatek.tags.google.GoogleMapIconTag;
import com.lamatek.tags.google.GoogleMapImageOverlayTag;
import com.lamatek.tags.google.GoogleMapInfoWindowTabbedTag;
import com.lamatek.tags.google.GoogleMapInfoWindowTag;
import com.lamatek.tags.google.GoogleMapInsertTag;
import com.lamatek.tags.google.GoogleMapKeyTag;
import com.lamatek.tags.google.GoogleMapLabelTag;
import com.lamatek.tags.google.GoogleMapMapTypeTag;
import com.lamatek.tags.google.GoogleMapMarkerTag;
import com.lamatek.tags.google.GoogleMapMessageTag;
import com.lamatek.tags.google.GoogleMapOverviewTag;
import com.lamatek.tags.google.GoogleMapPanControlTag;
import com.lamatek.tags.google.GoogleMapPointTag;
import com.lamatek.tags.google.GoogleMapPolygonTag;
import com.lamatek.tags.google.GoogleMapPolylineTag;
import com.lamatek.tags.google.GoogleMapScaleControlTag;
import com.lamatek.tags.google.GoogleMapTabTag;
import com.lamatek.tags.google.GoogleMapTag;
import com.lamatek.tags.google.GoogleMapTrafficTag;
import com.lamatek.tags.google.GoogleMapTypeControlTag;
import com.lamatek.tags.google.GoogleMapWMSTag;
import com.lamatek.tags.google.GoogleMapWheelControlTag;
import com.lamatek.tags.google.GoogleMapZoomControlTag;

/**
 * XMLParser
 * 
 * This class parses XML files and validates against the googlemaps.dtd. Developers
 * should not extend this class or override it's methods.
 * 
 * @author Tom Cole
 * @version 0.80
 */
public class XMLParser {

    /**
     * Parses the supplied XML file and adds discovered elements to the given
     * GoogleMapTag. Developers should not override this method.
     * 
     * @return True or false denoting whether or not the XML file was sucessfully parsed.
     */
    public static boolean parseXML(String url, GoogleMapTag mapTag) {
        boolean parsed = true;
        if (url == null) {
            parsed = false;
        }
        else {
            try {
    	        URLConnection con = new URL(url).openConnection();
    	        if (con != null) {
    	            InputStream input = con.getInputStream();
    	            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    	            factory.setValidating(true);
    	            DocumentBuilder parser = factory.newDocumentBuilder();
    	            Document elements = parser.parse(input);
    	            NodeList maps = elements.getElementsByTagName("map");
    	            for (int i = 0; i < maps.getLength(); i++) {
    	                Node map = maps.item(i);  
    	                //parse and set the attributes...
    	                NamedNodeMap attributes = map.getAttributes();
    	                if (attributes != null) {
    	                    if (attributes.getNamedItem("type") != null) {
    	                        mapTag.setType(attributes.getNamedItem("type").getNodeValue());
    	                    }
    	                    if (attributes.getNamedItem("headless") != null) {
    	                        mapTag.setHeadless(Boolean.parseBoolean(attributes.getNamedItem("headless").getNodeValue()));
    	                    }
    	                    if (attributes.getNamedItem("version") != null) {
    	                        mapTag.setVersion(attributes.getNamedItem("version").getNodeValue());
    	                    }
    	                    if (attributes.getNamedItem("language") != null) {
    	                    	mapTag.setLanguage(attributes.getNamedItem("language").getNodeValue());
    	                    }
    	                    if (attributes.getNamedItem("debug") != null) {
    	                        mapTag.setDebug(Boolean.parseBoolean(attributes.getNamedItem("debug").getNodeValue()));
    	                    }
    	                    if (attributes.getNamedItem("showDaylight") != null) {
    	                        mapTag.setShowDaylight(Boolean.parseBoolean(attributes.getNamedItem("showDaylight").getNodeValue()));
    	                    }
    	                    if (attributes.getNamedItem("zoom") != null) {
    	                        try {
    	                            mapTag.setZoom(Integer.parseInt(attributes.getNamedItem("zoom").getNodeValue()));
    	                        }
    	                        catch(NumberFormatException nfe) {}
    	                    }
    	                    if (attributes.getNamedItem("minZoom") != null) {
    	                        try {
    	                            mapTag.setMinZoom(Integer.parseInt(attributes.getNamedItem("minZoom").getNodeValue()));
    	                        }
    	                        catch(NumberFormatException nfe) {}
    	                    }
    	                    if (attributes.getNamedItem("maxZoom") != null) {
    	                        try {
    	                            mapTag.setMaxZoom(Integer.parseInt(attributes.getNamedItem("maxZoom").getNodeValue()));
    	                        }
    	                        catch(NumberFormatException nfe) {}
    	                    }
    	                    if (attributes.getNamedItem("bound") != null) {
    	                        try {
    	                            mapTag.setBound(Boolean.parseBoolean(attributes.getNamedItem("bound").getNodeValue()));
    	                        }
    	                        catch(Exception ex) {}
    	                    }
    	                    if (attributes.getNamedItem("scope") != null) {
    	                        mapTag.setScope(attributes.getNamedItem("scope").getNodeValue());
    	                    }
    	                    if (attributes.getNamedItem("width") != null) {
    	                        try {
    	                            mapTag.setWidth(attributes.getNamedItem("width").getNodeValue());
    	                        }
    	                        catch(NumberFormatException nfe) {}
    	                    }
    	                    if (attributes.getNamedItem("height") != null) {
    	                        try {
    	                            mapTag.setHeight(attributes.getNamedItem("height").getNodeValue());
    	                        }
    	                        catch(NumberFormatException nfe) {}
    	                    }
    	                    if (attributes.getNamedItem("centerLatitude") != null) {
    	                        try {
    	                            mapTag.setCenterLatitude(Double.parseDouble(attributes.getNamedItem("centerLatitude").getNodeValue()));
    	                        }
    	                        catch(NumberFormatException nfe) {}
    	                    }
    	                    if (attributes.getNamedItem("centerLongitude") != null) {
    	                        try {
    	                            mapTag.setCenterLongitude(Double.parseDouble(attributes.getNamedItem("centerLongitude").getNodeValue()));
    	                        }
    	                        catch(NumberFormatException nfe) {}
    	                    }
    	                }
    	                //Now parse the children...
    	                NodeList children = map.getChildNodes();
    	                for (int j = 0; j < children.getLength(); j++) {
    	                    Node child = children.item(j);
    	                    attributes = child.getAttributes();
    	                    if (child.getNodeName().equals("key")) {
    	                        GoogleMapKeyTag key = new GoogleMapKeyTag();
    	                        if (attributes != null) {
    	                            if (attributes.getNamedItem("domain") != null) {
    	                                key.setDomain(attributes.getNamedItem("domain").getNodeValue());
    	                            }
    	                            if (attributes.getNamedItem("key") != null) {
    	                                key.setKey(attributes.getNamedItem("key").getNodeValue());
    	                            }
    	                        }
    	                        mapTag.addKey(key);
    	                    }
    	                    else if (child.getNodeName().equals("cluster")) {
    	                        GoogleMapClusterTag cluster = new GoogleMapClusterTag();
    	                        if (attributes != null) {
    	                            if (attributes.getNamedItem("pathToScript") != null) {
    	                                cluster.setPathToScript(attributes.getNamedItem("pathToScript").getNodeValue());
    	                            } 
    	                            if (attributes.getNamedItem("maxVisibleMarkers") != null) {
    	                                cluster.setMaxVisibleMarkers(Integer.parseInt(attributes.getNamedItem("maxVisibleMarkers").getNodeValue()));
    	                            } 
    	                            if (attributes.getNamedItem("markersPerCluster") != null) {
    	                                cluster.setMaxVisibleMarkers(Integer.parseInt(attributes.getNamedItem("markersPerCluster").getNodeValue()));
    	                            } 
    	                            if (attributes.getNamedItem("gridSize") != null) {
    	                                cluster.setGridSize(Integer.parseInt(attributes.getNamedItem("gridSize").getNodeValue()));
    	                            }
    	                            if (child.getChildNodes() != null) {
    	                                NodeList subs = child.getChildNodes();
    	                                for (int k = 0; k < subs.getLength(); k++) {
    	                                    Node sub = subs.item(k);
        	                                attributes = sub.getAttributes();
        	                                if (sub.getNodeName().equals("icon")) {
        	                                    GoogleMapIconTag icon = new GoogleMapIconTag();
        	                                    if (attributes != null) {
        	                                        if (attributes.getNamedItem("icon") != null) {
        	                                            icon.setIcon(attributes.getNamedItem("icon").getNodeValue());
        	                                        }
        	                                        if (attributes.getNamedItem("shadow") != null) {
        	                                            icon.setShadow(attributes.getNamedItem("shadow").getNodeValue());
        	                                        }
        	                                        if (attributes.getNamedItem("iconWidth") != null) {
        	                                            icon.setIconWidth(Integer.parseInt(attributes.getNamedItem("iconWidth").getNodeValue()));
        	                                        }
        	                                        if (attributes.getNamedItem("iconHeight") != null) {
        	                                            icon.setIconHeight(Integer.parseInt(attributes.getNamedItem("iconHeight").getNodeValue()));
        	                                        }
        	                                        if (attributes.getNamedItem("shadowWidth") != null) {
        	                                            icon.setShadowWidth(Integer.parseInt(attributes.getNamedItem("shadowWidth").getNodeValue()));
        	                                        }
        	                                        if (attributes.getNamedItem("shadowHeight") != null) {
        	                                            icon.setShadowHeight(Integer.parseInt(attributes.getNamedItem("shadowHeight").getNodeValue()));
        	                                        }
        	                                        if (attributes.getNamedItem("anchorX") != null) {
        	                                            icon.setAnchorX(Integer.parseInt(attributes.getNamedItem("anchorX").getNodeValue()));
        	                                        }
        	                                        if (attributes.getNamedItem("anchorY") != null) {
        	                                            icon.setAnchorY(Integer.parseInt(attributes.getNamedItem("anchorY").getNodeValue()));
        	                                        }
        	                                        if (attributes.getNamedItem("infoWindowAnchorX") != null) {
        	                                            icon.setInfoWindowAnchorX(Integer.parseInt(attributes.getNamedItem("infoWindowAnchorX").getNodeValue()));
        	                                        }
        	                                        if (attributes.getNamedItem("infoWindowAnchorY") != null) {
        	                                            icon.setInfoWindowAnchorY(Integer.parseInt(attributes.getNamedItem("infoWindowAnchorY").getNodeValue()));
        	                                        }
        	                                    }
        	                                    cluster.setIcon(icon);
        	                                }
    	                                }
    	                            }
    	                        }
    	                        mapTag.setClusterer(cluster);
    	                    }
    	                    else if (child.getNodeName().equals("point")) {
    	                        GoogleMapPointTag point = new GoogleMapPointTag();
    	                        if (attributes != null) {
    	                            if (attributes.getNamedItem("id") != null) {
    	                                point.setId(attributes.getNamedItem("id").getNodeValue());
    	                            }
    	                            if (attributes.getNamedItem("address") != null) {
    	                                point.setAddress(attributes.getNamedItem("address").getNodeValue());
    	                            }
    	                            if (attributes.getNamedItem("city") != null) {
    	                                point.setCity(attributes.getNamedItem("city").getNodeValue());
    	                            }
    	                            if (attributes.getNamedItem("state") != null) {
    	                                point.setState(attributes.getNamedItem("state").getNodeValue());
    	                            }
    	                            if (attributes.getNamedItem("country") != null) {
    	                                point.setCountry(attributes.getNamedItem("country").getNodeValue());
    	                            }
    	                            if (attributes.getNamedItem("zip") != null) {
    	                                point.setZipcode(attributes.getNamedItem("zip").getNodeValue());
    	                            }
    	                            if (attributes.getNamedItem("longitude") != null) {
    	                                point.setLongitude(Double.parseDouble(attributes.getNamedItem("longitude").getNodeValue()));
    	                            }
    	                            if (attributes.getNamedItem("latitude") != null) {
    	                                point.setLatitude(Double.parseDouble(attributes.getNamedItem("latitude").getNodeValue()));
    	                            }
    	                        }
    	                        point.geocode();
    	                        mapTag.addPoint(point);
    	                    }
    	                    else if (child.getNodeName().equals("box")) {
    	                        GoogleMapBoxTag box = new GoogleMapBoxTag();
    	                        if (attributes != null) {
    	                            String pointlist = "";
    	                            int pointCount = 0;
    	                            if (attributes.getNamedItem("id") != null) {
    	                                box.setId(attributes.getNamedItem("id").getNodeValue());
    	                            }
    	                            if (attributes.getNamedItem("color") != null) {
    	                                box.setColor(attributes.getNamedItem("color").getNodeValue());
    	                            }
    	                            if (attributes.getNamedItem("opacity") != null) {
    	                                box.setOpacity(Float.parseFloat(attributes.getNamedItem("opacity").getNodeValue()));
    	                            }
    	                            if (attributes.getNamedItem("weight") != null) {
    	                                box.setWeight(Integer.parseInt(attributes.getNamedItem("weight").getNodeValue()));
    	                            }
    	                            if (attributes.getNamedItem("point1") != null) {
    	                                if (pointCount > 1)
    	                                    pointlist += ",";
    	                                pointlist += attributes.getNamedItem("point1").getNodeValue();
    	                                pointCount++;
    	                            }
    	                            if (attributes.getNamedItem("point2") != null) {
    	                                if (pointCount > 0)
    	                                    pointlist += ",";
    	                                pointlist += attributes.getNamedItem("point2").getNodeValue();
    	                            }
    	                            box.setPointlist(pointlist);
    	                        }
    	                        mapTag.addBox(box);
    	                    }
    	                    else if (child.getNodeName().equals("circle")) {
    	                        GoogleMapCircleTag circle = new GoogleMapCircleTag();
    	                        if (attributes != null) {
    	                            if (attributes.getNamedItem("id") != null) {
    	                                circle.setId(attributes.getNamedItem("id").getNodeValue());
    	                            }
    	                            if (attributes.getNamedItem("color") != null) {
    	                                circle.setColor(attributes.getNamedItem("color").getNodeValue());
    	                            }
    	                            if (attributes.getNamedItem("opacity") != null) {
    	                                circle.setOpacity(Float.parseFloat(attributes.getNamedItem("opacity").getNodeValue()));
    	                            }
    	                            if (attributes.getNamedItem("weight") != null) {
    	                                circle.setWeight(Integer.parseInt(attributes.getNamedItem("weight").getNodeValue()));
    	                            }
    	                            if (attributes.getNamedItem("point") != null) {
    	                                circle.setPoint(attributes.getNamedItem("point").getNodeValue());
    	                            }
    	                            if (attributes.getNamedItem("radius") != null) {
    	                                circle.setRadius(Double.parseDouble(attributes.getNamedItem("radius").getNodeValue()));
    	                            }
    	                        }
    	                        mapTag.addCircle(circle);
    	                    }
    	                    else if (child.getNodeName().equals("polyline")) {
    	                        GoogleMapPolylineTag line = new GoogleMapPolylineTag();
    	                        if (attributes != null) {
	    	                        if (attributes.getNamedItem("id") != null) {
		                                line.setId(attributes.getNamedItem("id").getNodeValue());
		                            }
		                            if (attributes.getNamedItem("color") != null) {
		                                line.setColor(attributes.getNamedItem("color").getNodeValue());
		                            }
		                            if (attributes.getNamedItem("opacity") != null) {
		                                line.setOpacity(Float.parseFloat(attributes.getNamedItem("opacity").getNodeValue()));
		                            }
		                            if (attributes.getNamedItem("weight") != null) {
		                                line.setWeight(Integer.parseInt(attributes.getNamedItem("weight").getNodeValue()));
		                            }
		                            if (attributes.getNamedItem("pointlist") != null) {
		                                line.setPointlist(attributes.getNamedItem("pointlist").getNodeValue().replaceAll(" ", ","));
		                            }
    	                        }
    	                        mapTag.addPolyline(line);
    	                    }
    	                    else if (child.getNodeName().equals("polygon")) {
    	                        GoogleMapPolygonTag polygon = new GoogleMapPolygonTag();
    	                        if (attributes != null) {
	    	                        if (attributes.getNamedItem("id") != null) {
	    	                            polygon.setId(attributes.getNamedItem("id").getNodeValue());
		                            }
		                            if (attributes.getNamedItem("color") != null) {
		                                polygon.setColor(attributes.getNamedItem("color").getNodeValue());
		                            }
		                            if (attributes.getNamedItem("opacity") != null) {
		                                polygon.setOpacity(Float.parseFloat(attributes.getNamedItem("opacity").getNodeValue()));
		                            }
		                            if (attributes.getNamedItem("weight") != null) {
		                                polygon.setWeight(Integer.parseInt(attributes.getNamedItem("weight").getNodeValue()));
		                            }
		                            if (attributes.getNamedItem("pointlist") != null) {
		                                polygon.setPointlist(attributes.getNamedItem("pointlist").getNodeValue().replaceAll(" ", ","));
		                            }
    	                        }
    	                        mapTag.addPolygon(polygon);
    	                    }
    	                    else if (child.getNodeName().equals("wms")) {
    	                        GoogleMapWMSTag maptype = new GoogleMapWMSTag();
    	                        if (attributes != null) {
    	                            if (attributes.getNamedItem("id") != null) {
    	                                maptype.setId(attributes.getNamedItem("id").getNodeValue());
    	                            }
    	                            if (attributes.getNamedItem("name") != null) {
    	                                maptype.setName(attributes.getNamedItem("name").getNodeValue());
    	                            }
    	                            if (attributes.getNamedItem("url") != null) {
    	                                maptype.setUrl(attributes.getNamedItem("url").getNodeValue());
    	                            }
    	                            if (attributes.getNamedItem("layers") != null) {
    	                                maptype.setLayers(attributes.getNamedItem("layers").getNodeValue());
    	                            }
    	                            if (attributes.getNamedItem("pathToScript") != null) {
    	                                maptype.setPathToScript(attributes.getNamedItem("pathToScript").getNodeValue());
    	                            }
    	                            if (attributes.getNamedItem("format") != null) {
    	                                maptype.setFormat(attributes.getNamedItem("format").getNodeValue());
    	                            }
    	                            if (attributes.getNamedItem("srs") != null) {
    	                                maptype.setSrs(attributes.getNamedItem("srs").getNodeValue());
    	                            }
    	                            if (attributes.getNamedItem("version") != null) {
    	                                maptype.setVersion(attributes.getNamedItem("version").getNodeValue());
    	                            }
    	                            if (attributes.getNamedItem("showOnStartup") != null) {
    	                                maptype.setShowOnStartup(Boolean.parseBoolean(attributes.getNamedItem("showOnStartup").getNodeValue()));
    	                            }
    	                            if (attributes.getNamedItem("showOverlay") != null) {
    	                                maptype.setShowOverlay(Boolean.parseBoolean(attributes.getNamedItem("showOverlay").getNodeValue()));
    	                            }
    	                        }
    	                        mapTag.addWMSTag(maptype);
    	                    }
    	                    else if (child.getNodeName().equals("maptype")) {
    	                        GoogleMapMapTypeTag maptype = new GoogleMapMapTypeTag();
    	                        if (attributes != null) {
    	                            if (attributes.getNamedItem("id") != null) {
    	                                maptype.setId(attributes.getNamedItem("id").getNodeValue());
    	                            }
    	                            if (attributes.getNamedItem("name") != null) {
    	                                maptype.setName(attributes.getNamedItem("name").getNodeValue());
    	                            }
    	                            if (attributes.getNamedItem("baseType") != null) {
    	                                maptype.setBaseType(attributes.getNamedItem("baseType").getNodeValue());
    	                            }
    	                            if (attributes.getNamedItem("copyright") != null) {
    	                                maptype.setCopyright(attributes.getNamedItem("copyright").getNodeValue());
    	                            }
    	                            if (attributes.getNamedItem("url") != null) {
    	                                maptype.setUrl(attributes.getNamedItem("url").getNodeValue());
    	                            }
    	                            if (attributes.getNamedItem("lowResUrl") != null) {
    	                                maptype.setLowResUrl(attributes.getNamedItem("lowResUrl").getNodeValue());
    	                            }
    	                            if (attributes.getNamedItem("overlayUrl") != null) {
    	                                maptype.setOverlayUrl(attributes.getNamedItem("overlayUrl").getNodeValue());
    	                            }
    	                            if (attributes.getNamedItem("upperLeftBound") != null) {
    	                                maptype.setUpperLeftBound(attributes.getNamedItem("upperLeftBound").getNodeValue());
    	                            }
    	                            if (attributes.getNamedItem("lowerRightBound") != null) {
    	                                maptype.setLowerRightBound(attributes.getNamedItem("lowerRightBound").getNodeValue());
    	                            }
    	                            if (attributes.getNamedItem("maxZoom") != null) {
    	                                maptype.setMaxZoom(Integer.parseInt(attributes.getNamedItem("maxZoom").getNodeValue()));
    	                            }
    	                            if (attributes.getNamedItem("minZoom") != null) {
    	                                maptype.setMinZoom(Integer.parseInt(attributes.getNamedItem("minZoom").getNodeValue()));
    	                            }
    	                            if (attributes.getNamedItem("showOnStartup") != null) {
    	                                maptype.setShowOnStartup(Boolean.parseBoolean(attributes.getNamedItem("showOnStartup").getNodeValue()));
    	                            }
    	                            if (attributes.getNamedItem("png") != null) {
    	                                maptype.setPng(Boolean.parseBoolean(attributes.getNamedItem("png").getNodeValue()));
    	                            }
    	                        }
    	                        mapTag.addMapType(maptype);
    	                    }
    	                    else if (child.getNodeName().equals("imageoverlay")) {
    	                        GoogleMapImageOverlayTag image = new GoogleMapImageOverlayTag();
    	                        if (attributes != null) {
    	                            if (attributes.getNamedItem("id") != null) {
    	                                image.setId(attributes.getNamedItem("id").getNodeValue());
    	                            }
    	                            if (attributes.getNamedItem("url") != null) {
    	                                image.setUrl(attributes.getNamedItem("url").getNodeValue());
    	                            }
    	                            if (attributes.getNamedItem("link") != null) {
    	                                image.setLink(attributes.getNamedItem("link").getNodeValue());
    	                            }
    	                            if (attributes.getNamedItem("opacity") != null) {
    	                                image.setOpacity(Float.parseFloat(attributes.getNamedItem("opacity").getNodeValue()));
    	                            }
    	                            if (attributes.getNamedItem("x") != null) {
    	                                image.setX(Integer.parseInt(attributes.getNamedItem("x").getNodeValue()));
    	                            }
    	                            if (attributes.getNamedItem("y") != null) {
    	                                image.setY(Integer.parseInt(attributes.getNamedItem("y").getNodeValue()));
    	                            }
    	                        }
    	                        mapTag.addImageOverlay(image);
    	                    }
    	                    else if (child.getNodeName().equals("panControl")) {
    	                        GoogleMapPanControlTag control = new GoogleMapPanControlTag();
    	                        if (attributes != null) {
    	                            if (attributes.getNamedItem("enable") != null) {
    	                                control.setEnable(Boolean.parseBoolean(attributes.getNamedItem("enable").getNodeValue()));
    	                            }
    	                        }
    	                        mapTag.setPanControl(control);
    	                    }
    	                    else if (child.getNodeName().equals("scaleControl")) {
    	                        GoogleMapScaleControlTag control = new GoogleMapScaleControlTag();
    	                        if (attributes != null) {
    	                            if (attributes.getNamedItem("enable") != null) {
    	                                control.setEnable(Boolean.parseBoolean(attributes.getNamedItem("enable").getNodeValue()));
    	                            }
    	                        }
    	                        mapTag.setScaleControl(control);
    	                    }
    	                    else if (child.getNodeName().equals("wheelControl")) {
    	                        GoogleMapWheelControlTag control = new GoogleMapWheelControlTag();
    	                        if (attributes != null) {
    	                            if (attributes.getNamedItem("enable") != null) {
    	                                control.setEnable(Boolean.parseBoolean(attributes.getNamedItem("enable").getNodeValue()));
    	                            }
    	                        }
    	                        mapTag.setWheelControl(control);
    	                    }
    	                    else if (child.getNodeName().equals("typeControl")) {
    	                        GoogleMapTypeControlTag control = new GoogleMapTypeControlTag();
    	                        if (attributes != null) {
    	                            if (attributes.getNamedItem("enable") != null) {
    	                                control.setEnable(Boolean.parseBoolean(attributes.getNamedItem("enable").getNodeValue()));
    	                            }
    	                        }
    	                        mapTag.setTypeControl(control);
    	                    }
    	                    else if (child.getNodeName().equals("zoomControl")) {
    	                        GoogleMapZoomControlTag control = new GoogleMapZoomControlTag();
    	                        if (attributes != null) {
    	                            if (attributes.getNamedItem("enable") != null) {
    	                                control.setEnable(Boolean.parseBoolean(attributes.getNamedItem("enable").getNodeValue()));
    	                            }
    	                            if (attributes.getNamedItem("size") != null) {
    	                                control.setSize(attributes.getNamedItem("size").getNodeValue());
    	                            }
    	                        }
    	                        mapTag.setZoomControl(control);
    	                    }
    	                    else if (child.getNodeName().equals("overviewControl")) {
    	                        GoogleMapOverviewTag control = new GoogleMapOverviewTag();
    	                        if (attributes != null) {
    	                            if (attributes.getNamedItem("width") != null) {
    	                                control.setWidth(Integer.parseInt(attributes.getNamedItem("width").getNodeValue()));
    	                            }
    	                            if (attributes.getNamedItem("height") != null) {
    	                                control.setHeight(Integer.parseInt(attributes.getNamedItem("height").getNodeValue()));
    	                            }
    	                            if (attributes.getNamedItem("x") != null) {
    	                                control.setX(Integer.parseInt(attributes.getNamedItem("x").getNodeValue()));
    	                            }
    	                            if (attributes.getNamedItem("y") != null) {
    	                                control.setY(Integer.parseInt(attributes.getNamedItem("y").getNodeValue()));
    	                            }
    	                        }
    	                        mapTag.setOverviewControl(control);
    	                    }
    	                    else if (child.getNodeName().equals("message")) {
    	                        GoogleMapMessageTag message = new GoogleMapMessageTag();
    	                        if (attributes != null) {
    	                            if (attributes.getNamedItem("style") != null) {
    	                                message.setStyle(attributes.getNamedItem("style").getNodeValue());
    	                            }
    	                        }
    	                        if (child.getChildNodes() != null) {
    	                            NodeList subs = child.getChildNodes();
    	                            for (int k = 0; k < subs.getLength(); k++) {
    	                                Node sub = subs.item(k);
    	                                if (sub.getNodeName().equals("#text")) {
    	                                    message.setMessage(sub.getNodeValue());
    	                                }
    	                            }
    	                        }
    	                        mapTag.setMessage(message);
    	                    }
    	                    else if (child.getNodeName().equals("coordinates")) {
    	                        GoogleMapCoordinatesTag coords = new GoogleMapCoordinatesTag();
    	                        if (attributes != null) {
    	                            if (attributes.getNamedItem("x") != null) {
    	                                coords.setX(Integer.parseInt(attributes.getNamedItem("x").getNodeValue()));
    	                            }
    	                            if (attributes.getNamedItem("y") != null) {
    	                                coords.setY(Integer.parseInt(attributes.getNamedItem("y").getNodeValue()));
    	                            }
    	                            if (attributes.getNamedItem("style") != null) {
    	                                coords.setStyle(attributes.getNamedItem("style").getNodeValue());
    	                            }
    	                            if (attributes.getNamedItem("css_class") != null) {
    	                                coords.setCss_class(attributes.getNamedItem("css_class").getNodeValue());
    	                            }
    	                        }
    	                        mapTag.addCoordinates(coords);
    	                    }
    	                    else if (child.getNodeName().equals("insert")) {
    	                        GoogleMapInsertTag insert = new GoogleMapInsertTag();
    	                        if (attributes != null) {
    	                            if (attributes.getNamedItem("id") != null) {
    	                                insert.setId(attributes.getNamedItem("id").getNodeValue());
    	                            }
    	                            if (attributes.getNamedItem("mapTypes") != null) {
    	                                insert.setMapTypes(attributes.getNamedItem("mapTypes").getNodeValue());
    	                            }
    	                            if (attributes.getNamedItem("point") != null) {
    	                                insert.setPoint(attributes.getNamedItem("point").getNodeValue());
    	                            }  
    	                            if (attributes.getNamedItem("url") != null) {
    	                                insert.setUrl(attributes.getNamedItem("url").getNodeValue());
    	                            } 
    	                            if (attributes.getNamedItem("baseZoom") != null) {
    	                                insert.setBaseZoom(Integer.parseInt(attributes.getNamedItem("baseZoom").getNodeValue()));
    	                            }
    	                            if (attributes.getNamedItem("width") != null) {
    	                                insert.setWidth(Integer.parseInt(attributes.getNamedItem("width").getNodeValue()));
    	                            }
    	                            if (attributes.getNamedItem("height") != null) {
    	                                insert.setHeight(Integer.parseInt(attributes.getNamedItem("height").getNodeValue()));
    	                            }
    	                        }
    	                        mapTag.addInsert(insert);
    	                    }
    	                    else if (child.getNodeName().equals("label")) {
    	                        GoogleMapLabelTag label = new GoogleMapLabelTag();
    	                        if (attributes != null) {
    	                            if (attributes.getNamedItem("point") != null) {
    	                                label.setPoint(attributes.getNamedItem("point").getNodeValue());
    	                            }    
    	                            if (attributes.getNamedItem("css_class") != null) {
    	                                label.setCss_class(attributes.getNamedItem("css_class").getNodeValue());
    	                            } 
    	                            if (attributes.getNamedItem("content") != null) {
    	                                label.setContent(attributes.getNamedItem("content").getNodeValue());
    	                            } 
    	                            if (attributes.getNamedItem("html") != null) {
    	                                label.setHtml(Boolean.parseBoolean(attributes.getNamedItem("html").getNodeValue()));
    	                            } 
    	                            if (attributes.getNamedItem("style") != null) {
    	                                label.setStyle(attributes.getNamedItem("style").getNodeValue());
    	                            } 
    	                            if (attributes.getNamedItem("opacity") != null) {
    	                                label.setOpacity(Float.parseFloat(attributes.getNamedItem("opacity").getNodeValue()));
    	                            } 
    	                            if (attributes.getNamedItem("x_offset") != null) {
    	                                label.setX_offset(Integer.parseInt(attributes.getNamedItem("x_offset").getNodeValue()));
    	                            } 
    	                            if (attributes.getNamedItem("y_offset") != null) {
    	                                label.setY_offset(Integer.parseInt(attributes.getNamedItem("y_offset").getNodeValue()));
    	                            } 
    	                        }
    	                        if (child.getChildNodes() != null) {
    	                            NodeList subs = child.getChildNodes();
    	                            for (int k = 0; k < subs.getLength(); k++) {
    	                                Node sub = subs.item(k);
    	                                if (sub.getNodeName().equals("#text")) {
    	                                    label.setContent(sub.getNodeValue());
    	                                }
    	                            }
    	                        }
    	                        mapTag.addLabel(label);
    	                    }
    	                    else if (child.getNodeName().equals("traffic")) {
    	                        GoogleMapTrafficTag traffic = new GoogleMapTrafficTag();
    	                        if (attributes != null) {
    	                            if (attributes.getNamedItem("id") != null) {
    	                                traffic.setId(attributes.getNamedItem("id").getNodeValue());
    	                            }
    	                            if (attributes.getNamedItem("point") != null) {
    	                                traffic.setPoint(attributes.getNamedItem("point").getNodeValue());
    	                            }
    	                            if (attributes.getNamedItem("radius") != null) {
    	                                traffic.setRadius(Double.parseDouble(attributes.getNamedItem("radius").getNodeValue()));
    	                            }
    	                            if (attributes.getNamedItem("severity") != null) {
    	                                traffic.setSeverity(Integer.parseInt(attributes.getNamedItem("severity").getNodeValue()));
    	                            }
    	                            if (attributes.getNamedItem("type") != null) {
    	                                traffic.setType(attributes.getNamedItem("type").getNodeValue());
    	                            }
    	                        }
    	                        if (child.getChildNodes() != null) {
    	                            NodeList subs = child.getChildNodes();
    	                            for (int k = 0; k < subs.getLength(); k++) {
    	                                Node sub = subs.item(k);
    	                                attributes = sub.getAttributes();
    	                                if (sub.getNodeName().equals("icon")) {
    	                                    GoogleMapIconTag icon = new GoogleMapIconTag();
    	                                    if (attributes != null) {
    	                                        if (attributes.getNamedItem("icon") != null) {
    	                                            icon.setIcon(attributes.getNamedItem("icon").getNodeValue());
    	                                        }
    	                                        if (attributes.getNamedItem("shadow") != null) {
    	                                            icon.setShadow(attributes.getNamedItem("shadow").getNodeValue());
    	                                        }
    	                                        if (attributes.getNamedItem("iconWidth") != null) {
    	                                            icon.setIconWidth(Integer.parseInt(attributes.getNamedItem("iconWidth").getNodeValue()));
    	                                        }
    	                                        if (attributes.getNamedItem("iconHeight") != null) {
    	                                            icon.setIconHeight(Integer.parseInt(attributes.getNamedItem("iconHeight").getNodeValue()));
    	                                        }
    	                                        if (attributes.getNamedItem("shadowWidth") != null) {
    	                                            icon.setShadowWidth(Integer.parseInt(attributes.getNamedItem("shadowWidth").getNodeValue()));
    	                                        }
    	                                        if (attributes.getNamedItem("shadowHeight") != null) {
    	                                            icon.setShadowHeight(Integer.parseInt(attributes.getNamedItem("shadowHeight").getNodeValue()));
    	                                        }
    	                                        if (attributes.getNamedItem("anchorX") != null) {
    	                                            icon.setAnchorX(Integer.parseInt(attributes.getNamedItem("anchorX").getNodeValue()));
    	                                        }
    	                                        if (attributes.getNamedItem("anchorY") != null) {
    	                                            icon.setAnchorY(Integer.parseInt(attributes.getNamedItem("anchorY").getNodeValue()));
    	                                        }
    	                                        if (attributes.getNamedItem("infoWindowAnchorX") != null) {
    	                                            icon.setInfoWindowAnchorX(Integer.parseInt(attributes.getNamedItem("infoWindowAnchorX").getNodeValue()));
    	                                        }
    	                                        if (attributes.getNamedItem("infoWindowAnchorY") != null) {
    	                                            icon.setInfoWindowAnchorY(Integer.parseInt(attributes.getNamedItem("infoWindowAnchorY").getNodeValue()));
    	                                        }
    	                                    }
    	                                    traffic.setIcon(icon);
    	                                }
    	                            }
    	                        }
    	                        mapTag.addTraffic_tag(traffic);
    	                    }
    	                    else if (child.getNodeName().equals("marker")) {
    	                        GoogleMapMarkerTag marker = new GoogleMapMarkerTag();
    	                        if (attributes != null) {
    	                            if (attributes.getNamedItem("id") != null) {
    	                                marker.setId(attributes.getNamedItem("id").getNodeValue());
    	                            }
    	                            if (attributes.getNamedItem("point") != null) {
    	                                marker.setPoint(attributes.getNamedItem("point").getNodeValue());
    	                            }
    	                            if (attributes.getNamedItem("draggable") != null) {
    	                                marker.setDraggable(Boolean.parseBoolean(attributes.getNamedItem("draggable").getNodeValue()));
    	                            }
    	                        }
    	                        if (child.getChildNodes() != null) {
    	                            NodeList subs = child.getChildNodes();
    	                            for (int k = 0; k < subs.getLength(); k++) {
    	                                Node sub = subs.item(k);
    	                                attributes = sub.getAttributes();
    	                                if (sub.getNodeName().equals("icon")) {
    	                                    GoogleMapIconTag icon = new GoogleMapIconTag();
    	                                    if (attributes != null) {
    	                                        if (attributes.getNamedItem("icon") != null) {
    	                                            icon.setIcon(attributes.getNamedItem("icon").getNodeValue());
    	                                        }
    	                                        if (attributes.getNamedItem("shadow") != null) {
    	                                            icon.setShadow(attributes.getNamedItem("shadow").getNodeValue());
    	                                        }
    	                                        if (attributes.getNamedItem("iconWidth") != null) {
    	                                            icon.setIconWidth(Integer.parseInt(attributes.getNamedItem("iconWidth").getNodeValue()));
    	                                        }
    	                                        if (attributes.getNamedItem("iconHeight") != null) {
    	                                            icon.setIconHeight(Integer.parseInt(attributes.getNamedItem("iconHeight").getNodeValue()));
    	                                        }
    	                                        if (attributes.getNamedItem("shadowWidth") != null) {
    	                                            icon.setShadowWidth(Integer.parseInt(attributes.getNamedItem("shadowWidth").getNodeValue()));
    	                                        }
    	                                        if (attributes.getNamedItem("shadowHeight") != null) {
    	                                            icon.setShadowHeight(Integer.parseInt(attributes.getNamedItem("shadowHeight").getNodeValue()));
    	                                        }
    	                                        if (attributes.getNamedItem("anchorX") != null) {
    	                                            icon.setAnchorX(Integer.parseInt(attributes.getNamedItem("anchorX").getNodeValue()));
    	                                        }
    	                                        if (attributes.getNamedItem("anchorY") != null) {
    	                                            icon.setAnchorY(Integer.parseInt(attributes.getNamedItem("anchorY").getNodeValue()));
    	                                        }
    	                                        if (attributes.getNamedItem("infoWindowAnchorX") != null) {
    	                                            icon.setInfoWindowAnchorX(Integer.parseInt(attributes.getNamedItem("infoWindowAnchorX").getNodeValue()));
    	                                        }
    	                                        if (attributes.getNamedItem("infoWindowAnchorY") != null) {
    	                                            icon.setInfoWindowAnchorY(Integer.parseInt(attributes.getNamedItem("infoWindowAnchorY").getNodeValue()));
    	                                        }
    	                                    }
    	                                    marker.setIcon(icon);
    	                                }
    	                                else if (sub.getNodeName().equals("blowup")) {
    	                                    GoogleMapBlowupTag blowup = new GoogleMapBlowupTag();
    	                                    if (attributes != null) {
    	                                        if (attributes.getNamedItem("display") != null) {
    	                                            blowup.setDisplay(Boolean.parseBoolean(attributes.getNamedItem("display").getNodeValue()));
    	                                        }
    	                                        if (attributes.getNamedItem("maptype") != null) {
    	                                            blowup.setMaptype(attributes.getNamedItem("maptype").getNodeValue());
    	                                        }
    	                                        if (attributes.getNamedItem("zoom") != null) {
    	                                            blowup.setZoom(Integer.parseInt(attributes.getNamedItem("zoom").getNodeValue()));
    	                                        }
    	                                    }
    	                                    marker.setBlowup(blowup);
    	                                }
    	                                else if (sub.getNodeName().equals("infowindow")) {
    	                                    GoogleMapInfoWindowTag info = new GoogleMapInfoWindowTag();
    	                                    if (attributes != null) {
    	                                        if (attributes.getNamedItem("display") != null) {
    	                                            info.setDisplay(Boolean.parseBoolean(attributes.getNamedItem("display").getNodeValue()));
    	                                        }
    	                                        if (attributes.getNamedItem("content") != null) {
    	                                            info.setContent(attributes.getNamedItem("content").getNodeValue());
    	                                        }
    	                                        if (attributes.getNamedItem("html") != null) {
    	                                            info.setHtml(Boolean.parseBoolean(attributes.getNamedItem("html").getNodeValue()));
    	                                        }
    	                                    }
    	                                    
    	                                    if (sub.getChildNodes() != null) {
    	                                        NodeList subSubs = sub.getChildNodes();
    	                                        for (int l = 0; l < subSubs.getLength(); l++) {
    	                                            Node subSub = subSubs.item(l);
    	                                            if (subSub.getNodeName().equals("#text")) {
    	                                                info.setContent(subSub.getNodeValue());
    	                                            }
    	                                        }
    	                                    }
    	                                    marker.setInfoWindow(info);
    	                                }
    	                                else if (sub.getNodeName().equals("tabbedInfoWindow")) {
    	                                    GoogleMapInfoWindowTabbedTag info = new GoogleMapInfoWindowTabbedTag();
    	                                    if (attributes != null) {
    	                                        if (attributes.getNamedItem("display") != null) {
    	                                            info.setDisplay(Boolean.parseBoolean(attributes.getNamedItem("display").getNodeValue()));
    	                                        }
    	                                    }
    	                                    if (sub.getChildNodes() != null) {
    	                                        NodeList subSubs = sub.getChildNodes();
    	                                        for (int l = 0; l < subSubs.getLength(); l++) {
    	                                            Node subSub = subSubs.item(l);
    	                                            if (subSub.getNodeName().equals("tab")) {
    	                                                GoogleMapTabTag tab = new GoogleMapTabTag();
    	                                                attributes = subSub.getAttributes();
    	                                                if (attributes != null) {
    	                                                    if (attributes.getNamedItem("label") != null) {
    	                                                        tab.setLabel(attributes.getNamedItem("label").getNodeValue());
    	                                                    }
    	                                                    if (attributes.getNamedItem("content") != null) {
    	                                                        tab.setContent(attributes.getNamedItem("content").getNodeValue());
    	                                                    }
    	                                                    if (attributes.getNamedItem("html") != null) {
    	        	                                            tab.setHtml(Boolean.parseBoolean(attributes.getNamedItem("html").getNodeValue()));
    	        	                                        }
    	                                                }
    	                                                NodeList subSubSubs = subSub.getChildNodes();
    	                                                for (int m = 0; m < subSubSubs.getLength(); m++) {
    	                                                    Node subSubSub = subSubSubs.item(m);
    	                                                    if (subSubSub.getNodeName().equals("#text")) {
    	                                                        tab.setContent(subSubSub.getNodeValue());
    	                                                    }
    	                                                }
    	                                                info.addTab(tab);
    	                                            }
    	                                        }
    	                                    }
    	                                    marker.setInfoWindow(info);
    	                                }
    	                                else if (sub.getNodeName().equals("event")) {
    	                                    GoogleMapEventTag event = new GoogleMapEventTag();
    	                                    if (attributes != null) {
    	                                        if (attributes.getNamedItem("action") != null) {
    	                                            event.setAction(attributes.getNamedItem("action").getNodeValue());
    	                                        }
    	                                        if (attributes.getNamedItem("url") != null) {
    	                                            event.setUrl(attributes.getNamedItem("url").getNodeValue());
    	                                        }
    	                                        if (attributes.getNamedItem("asynchronous") != null) {
    	                                            event.setAsynchronous(Boolean.parseBoolean(attributes.getNamedItem("asynchronous").getNodeValue()));
    	                                        }
    	                                    }
    	                                    marker.addEvent(event);
    	                                }
    	                            }
    	                        }
    	                        mapTag.addMarker(marker);
    	                    }
    	                    else if (child.getNodeName().equals("event")) {
    	                        GoogleMapEventTag event = new GoogleMapEventTag();
    	                        if (attributes != null) {
    	                            if (attributes.getNamedItem("action") != null) {
                                        event.setAction(attributes.getNamedItem("action").getNodeValue());
                                    }
                                    if (attributes.getNamedItem("url") != null) {
                                        event.setUrl(attributes.getNamedItem("url").getNodeValue());
                                    }
                                    if (attributes.getNamedItem("asynchronous") != null) {
                                        event.setAsynchronous(Boolean.parseBoolean(attributes.getNamedItem("asynchronous").getNodeValue()));
                                    }
                                }
    	                        mapTag.addEvent(event);
    	                    }
    	                }
    	            }
    	        }
            }
            catch(Exception ex) {
                ex.printStackTrace(System.err);
                parsed = false;
            }
        }
        return parsed;
    }
}
